package com.kexun.platform.migu;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gargoylesoftware.htmlunit.util.UrlUtils;
import com.kexun.bo.PlayUrlBO;
import com.kexun.bo.SongBO;
import com.kexun.utils.HttpUtils;
import org.apache.commons.io.FileUtils;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.StringUtils;
import sun.net.util.URLUtil;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.io.*;
import java.net.URI;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Entrance {

    public static String globalCookie = "WT_FPC=id=2ef309ec327918c6ab11626446834293:lv=1649775788739:ss=1649774005928; mg_uem_user_id_9fbe6599400e43a4a58700a822fd57f8=e2775395-e269-4cf8-bd7a-be95af8d2980; cookieId=jUtxsd0GgGVh88wpYMqt1pfpJ0sjDsRE1630812888215; migu_cookie_id=5a26175b-1daf-4eef-81e6-6d1f0711a3c1-n41649151214018; idmpauth=true@passport.migu.cn; migu_music_status=true; migu_music_uid=be8d8f69-2cc5-4775-8cc5-a4d54bd8bb60; migu_music_avatar=%252F%252Fcdnmusic.migu.cn%252Fv3%252Fstatic%252Fimg%252Fcommon%252Fheader%252Fdefault-avatar.png; migu_music_nickname=%E5%92%AA%E5%92%95%E9%9F%B3%E4%B9%90%E7%94%A8%E6%88%B7; migu_music_level=0; migu_music_credit_level=1; migu_music_platinum=0; migu_music_msisdn=LTpg9WQc6wrTX4tM2Wvrmw%3D%3D; migu_music_email=; migu_music_passid=249713539620604629; migu_music_sid=s%3AF8yV1ChqSppDmOepWb-gPElVX0uaHL69.mEOmSBhZyfLtNCcN4JXf61upB%2B15JdxBFRqMSbQ16Qg; player_stop_open=0; playlist_adding=1; addplaylist_has=1; audioplayer_new=1; playlist_change=0; add_play_now=1; audioplayer_open=1; audioplayer_exist=1";

    public List<SongBO> getKeyWordSong(String url) {
        List<SongBO> songList = new ArrayList<>();
        try {
            Connection connect = Jsoup.connect(url);
            Map<String, String> header = createHeader();
            for (String key : header.keySet()) {
                connect.header(key, header.get(key));
            }
            Document document = connect.get();
            Elements elementsByClass = document.getElementsByClass("J_CopySong");
            for (Element songItem : elementsByClass) {
                String songCid = songItem.attr("data-cid");
                SongBO songBO = getSongDetail(songCid);
                System.out.println("扫描到:" + songBO.getSongName() + "-" + songBO.getSinger());
                songList.add(songBO);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


        return songList;
    }

    public List<SongBO> getSingerSong(String url) {
        List<SongBO> songList = new ArrayList<>();
        try {
            int totalPage = 1;
            int cuttPage = 1;
            while (cuttPage <= totalPage) {
                String urlc = url + "?page=" + cuttPage;
                Connection connect = Jsoup.connect(urlc);
                Map<String, String> header = createHeader();
                for (String key : header.keySet()) {
                    connect.header(key, header.get(key));
                }
                Document document = connect.get();
                Elements pagination = document.getElementsByClass("pagination-item");
                if (pagination.size() != 0 && totalPage == 1) {
                    Element element = pagination.get(pagination.size() - 1);
                    totalPage = Integer.parseInt(element.text());
                }

                Elements elementsByClass = document.getElementsByClass("J_CopySong");
                for (Element songItem : elementsByClass) {
                    String songName = songItem.getElementsByClass("song-name-txt").first().text();
                    String songCid = songItem.attr("data-cid");
                    SongBO songBO = getSongDetail(songCid);
                    System.out.println("扫描到:" + songBO.getSongName() + "-" + songBO.getSinger() + " size:" + songList.size());
                    songList.add(songBO);
                }
                cuttPage++;
            }
        } catch (Exception e) {

        }


        return songList;
    }

    static Invocable invoke;

    static {
        try {
            ScriptEngineManager manager = new ScriptEngineManager();
            ScriptEngine engine = manager.getEngineByName("JavaScript");
            engine.eval(new InputStreamReader(new ClassPathResource("js/jsencrypt.min.js").getInputStream()));
            engine.eval(new InputStreamReader(new ClassPathResource("js/aes.js").getInputStream()));
            engine.eval(new InputStreamReader(new ClassPathResource("js/pad-zeropadding-min.js").getInputStream()));
            engine.eval(new InputStreamReader(new ClassPathResource("js/getPlayInfo.js").getInputStream()));
            invoke = (Invocable) engine;
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public String getPlayInfo(String copyrightId, int type) {
        try {
            String playReqUrl = (String) invoke.invokeFunction("getPlayInfo", copyrightId, type);
            Map<String, String> header = createHeader();
            return HttpUtils.doGet(playReqUrl, header);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }


    public String getLyricInfo(String copyrightId) {
        try {
            String playReqUrl = "https://music.migu.cn/v3/api/music/audioPlayer/getLyric?copyrightId=" + copyrightId;
            Map<String, String> header = createHeader();
            String s = HttpUtils.doGet(playReqUrl, header);
            JSONObject resJson = JSON.parseObject(s);
            String lyric = resJson.getString("lyric");
            return lyric;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }


    public void saveMusicToFile(String copyrightId, String path, String fileName, int type) {
        try {
            String playInfo = getPlayInfo(copyrightId, type);
            System.out.println(playInfo);
            JSONObject resJson = JSON.parseObject(playInfo);
            JSONObject data = resJson.getJSONObject("data");
            String playUrl = data.getString("playUrl");
            path = path.replace(" ", "").replace("|", "");
            File file = new File(path);
            if (!file.exists()) {
                file.mkdirs();
            }
            File file1 = new File(path + "\\" + fileName);
            System.out.println("播放地址：" + playUrl);
            playUrl = "http:" + playUrl;
            playUrl = urlEncodeChinese(playUrl);
            System.out.println(playUrl);
            FileUtils.copyURLToFile(new URL(playUrl), file1);
            System.out.println("保存成功:" + file1.getPath());
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("保存失败:" + fileName + " 错误:" + e.getMessage());
        }

    }

    public static String urlEncodeChinese(String url) {
        try {
            Matcher matcher = Pattern.compile("[\\u4e00-\\u9fa5]").matcher(url);
            String tmp = "";
            while (matcher.find()) {
                tmp = matcher.group();
                url = url.replaceAll(tmp, URLEncoder.encode(tmp, "UTF-8"));
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return url;
    }


    public List<Map<String, String>> getSingerList() {
        List<Map<String, String>> maps = new ArrayList<>();
        try {
            Connection connect = Jsoup.connect("https://music.migu.cn/v3/music/artist?tagId=1&type=A&firstLetter=1&page=1");
            Map<String, String> header = createHeader();
            for (String key : header.keySet()) {
                connect.header(key, header.get(key));
            }
            Document document = connect.get();
            Elements thumbnails = document.getElementsByClass("thumbnail");
            for (Element thumbnail : thumbnails) {
                Element thumb_link = thumbnail.getElementsByClass("thumb-link").first();
                String href = thumb_link.attr("href");
                href = "https://music.migu.cn" + href + "/song";
                String singer = thumb_link.getElementsByTag("span").text();
                HashMap<String, String> map = new HashMap<>();
                map.put("href", href);
                map.put("singer", singer);
                maps.add(map);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return maps;
    }


    //获取推荐歌单
    public JSONArray getTjGdList() {
        return getGdList("");
    }

    public JSONArray getGdListByTagID(String tagID) {
        return getGdList(tagID);
    }

    //获取所有歌单
    public JSONArray getGdList(String tagId) {
        JSONArray list = new JSONArray();
        try {
            //下载页码
            int totalPage = 120;
            int cuttPage = 1;
            while (cuttPage <= totalPage) {
                System.out.println("开始加载歌歌单第[" + cuttPage + "]页");
                try {
                    Connection connect = Jsoup.connect("https://music.migu.cn/v3/music/playlist?tagId=" + tagId + "&page=" + cuttPage);
                    Map<String, String> header = createHeader();
                    for (String key : header.keySet()) {
                        connect.header(key, header.get(key));
                    }
                    Document document = connect.get();
                    Element page = document.getElementsByClass("page").first();
                    Elements a = page.getElementsByTag("a");
                    if (a.size() != 0) {
                        Element element = a.get(a.size() - 2);
                        totalPage = Integer.parseInt(element.text());
                    }

                    Elements thumbs = document.getElementsByClass("thumb");
                    for (Element thumb : thumbs) {
                        try {
                            JSONObject item = new JSONObject();
                            Element music_cover = thumb.getElementsByClass("music-cover").first();
                            Element tag_a = music_cover.getElementsByTag("a").first();
                            String imgUrl = tag_a.getElementsByTag("img").first().attr("data-original");
                            Element span = music_cover.getElementsByTag("span").first();
                            //歌单id
                            String originId = span.attr("data-id");
                            Element song_list_name = thumb.getElementsByClass("song-list-name").first();
                            String title = song_list_name.getElementsByTag("a").text();
                            String bfl = thumb.getElementsByClass("desc-text").first().text();
                            item.put("gdId", originId);
                            item.put("gdName", title);
                            System.out.println("加载歌单:" + item.toJSONString());
                            list.add(item);
                        } catch (Exception e) {
                        }
                    }
                    cuttPage++;
                } catch (Exception e) {

                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }


    /**
     * 根据歌单id获取歌单所有的音乐信息
     *
     * @param gdId
     * @return
     */
    public List<SongBO> getGdSong(String gdId) {
        List<SongBO> songList = new ArrayList<>();
        try {
            int totalPage = 1;
            int cuttPage = 1;
            while (cuttPage <= totalPage) {
                System.out.println("开始加载歌曲第[" + cuttPage + "]页");
                String url = "https://music.migu.cn/v3/music/playlist/" + gdId + "?page=" + cuttPage;
                Document document = getDocument(url);
                Element page = document.getElementsByClass("page").first();
                Elements a = page.getElementsByTag("a");
                if (a.size() != 0 && totalPage == 1) {
                    Element element = a.get(a.size() - 2);
                    totalPage = Integer.parseInt(element.text());
                }
                Elements elementsByClass = document.getElementsByClass("J_CopySong");
                for (Element songItem : elementsByClass) {
                    String songCid = songItem.attr("data-cid");
                    SongBO songDetail = getSongDetail(songCid);
                    if (songDetail != null) {
                        System.out.println("加载歌曲:" + songDetail.getSongName());
                        songList.add(songDetail);
                    }

                }
                cuttPage++;

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return songList;
    }

    public static void main(String[] args) {
        Entrance entrance = new Entrance();
        List<SongBO> songBOList = entrance.getKeyWordSong("https://music.migu.cn/v3/search?page=2&type=song&i=ba79dc8475bdcd39b2b51121f8e6ba6aeb8511ad&f=html&s=1649758851&c=001002A&keyword=%E7%A5%81%E9%9A%86&v=3.22.7");
        for (SongBO songBO : songBOList) {
            System.out.println(songBO.getSongName());
        }
    }

    public List<String> getFilterTagList() {
        ArrayList<String> list = new ArrayList<>();
        Document document = getDocument("https://music.migu.cn/v3/music/playlist");
        Elements elements = document.select(".tag-list li a");
        for (Element element : elements) {
            String href = element.attr("href");
            if (href.contains("javascript")) {
                continue;
            }
            list.add(href.substring(href.indexOf("=") + 1));
        }
        return list;
    }

    /**
     * 根据cid获取歌曲信息
     *
     * @return
     */
    public SongBO getSongDetail(String cid) {
        try {
            String url = "https://music.migu.cn/v3/music/song/" + cid;
            Document document = getDocument(url);
            SongBO songBO = new SongBO();
            songBO.setSongImg(getSongImage(document));
            songBO.setSongName(getSongName(document));
            songBO.setSinger(getSinger(document));
            songBO.setAlbumName(getAlbumName(document));
            songBO.setPlayUrls(getPlayUrls(cid));
            songBO.setLrcText(getLyricInfo(cid));
            return songBO;
        } catch (Exception e) {
            System.err.println("获取歌曲详情失败");
            return null;
        }

    }


    public Document getDocument(String url) {
        try {
            Connection connect = Jsoup.connect(url);
            Map<String, String> header = createHeader();
            for (String key : header.keySet()) {
                connect.header(key, header.get(key));
            }
            return connect.timeout(10000).get();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }


    private String getSongImage(Document document) {
        try {
            return "http:" + document.getElementsByClass("img_contain").first().getElementsByClass("lazy-img").first().attr("data-original");
        } catch (Exception e) {
            return null;
        }
    }

    private String getSongName(Document document) {
        try {
            return document.getElementsByClass("info_title").first().text();
        } catch (Exception e) {
            return null;
        }
    }

    private String getSinger(Document document) {
        try {
            return document.getElementsByClass("info_singer").first().text();
        } catch (Exception e) {
            return null;
        }
    }

    private String getAlbumName(Document document) {
        try {
            return document.getElementsMatchingOwnText("所属专辑：").first().getElementsByTag("a").first().text();
        } catch (Exception e) {
            return null;
        }
    }


    public List<PlayUrlBO> getPlayUrls(String cid) {
        try {
            List<PlayUrlBO> resList = new ArrayList<>();
            for (int i = 0; i < 3; i++) {
                int type = i + 1;
                String playUrl = getPlayUrl(cid, type);
                if (!StringUtils.isEmpty(playUrl)) {
                    resList.add(new PlayUrlBO(type, playUrl));
                }
            }
            return resList;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }

    public String getPlayUrl(String cid, int type) {
        try {
            String playInfo = getPlayInfo(cid, type);
            if (StringUtils.isEmpty(playInfo)) {
                return null;
            }
            JSONObject resJson = JSON.parseObject(playInfo);
            JSONObject data = resJson.getJSONObject("data");

            String playUrl = data.getString("playUrl");
            if (StringUtils.isEmpty(playUrl)) {
                return null;
            }
            playUrl = "http:" + playUrl;
            playUrl = urlEncodeChinese(playUrl);
            return playUrl;
        } catch (Exception e) {
            System.err.println("播放地址加载失败");
            return null;
        }

    }


    public Map<String, String> createHeader() {
        HashMap<String, String> headers = new HashMap<>();
        headers.put("Host", "music.migu.cn");
        headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:87.0) Gecko/20100101 Firefox/87.0");
        headers.put("Accept", "application/json, text/plain, */*");
        headers.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
        headers.put("Accept-Encoding", "gzip, deflate, br");
        headers.put("Connection", "keep-alive");
        headers.put("Referer", "https://music.migu.cn/v3/music/player/audio");
        headers.put("Cookie", globalCookie);
        headers.put("Pragma", "no-cache");
        headers.put("Cache-Control", "no-cache");
        return headers;
    }


}
